/** The Item Editor manages the various panel which are needed to display Items Information
 * and Multimedia Content. Listen to all the other components of the GUI.
 *@author zulianp@lu.unisi.ch & lemmar@lu.unisi.ch
 */

package ch.unisi.inf.projects.java.uom.gui.itemeditor;

import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import java.awt.*;

import ch.unisi.inf.projects.java.uom.elements.*;
import ch.unisi.inf.projects.java.uom.gui.ToolBarListener;
import ch.unisi.inf.projects.java.uom.gui.itemeditor.fieldselector.FieldSelectorPanel;
import ch.unisi.inf.projects.java.uom.gui.itemeditor.multimedia.MultimediaSelectorPanel;
import ch.unisi.inf.projects.java.uom.gui.itemeditor.multimedia.PhotoPanel;
import ch.unisi.inf.projects.java.uom.gui.itemeditor.multimedia.PhotoPanelListener;
import ch.unisi.inf.projects.java.uom.gui.table.UOMItemClassJTable;
import ch.unisi.inf.projects.java.uom.gui.table.UOMItemJTable;
import ch.unisi.inf.projects.java.uom.gui.table.item.UOMItemJTableListener;
import ch.unisi.inf.projects.java.uom.gui.table.itemclass.UOMItemClassJTableListener;
import ch.unisi.inf.projects.java.uom.exceptions.UOMException;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
import java.util.List;

public final class ItemEditor extends JPanel implements UOMItemJTableListener, ItemManagerListener,
													UOMItemClassJTableListener, PhotoPanelListener, ToolBarListener
{
	private static final long serialVersionUID = -1L;
	private ItemClass itemClass;
    private Item item;
    private final List<Photo> photos;
    private Photo preview;
    private final PhotoPanel previewPanel;
    private boolean multimediaModified;
    private MultimediaSelectorPanel slidingWindow;
    private FieldSelectorPanel fieldsPanel;
    private ArrayList<ItemEditorListener> listeners = new ArrayList<ItemEditorListener>();
	private UOMItemJTable linkedItemTable;
    private JSplitPane JSPV;
    private JSplitPane JSPH;
    
    public ItemEditor(final ItemClass itemClass,final UOMItemJTable linkedItemTable)
    {
    	this.linkedItemTable =  linkedItemTable;
    	if((itemClass != null) && (!itemClass.toString().contains("ALL CATEGORIES"))){
    		final Item newItem = ItemManager.instance().itemAdd(itemClass, false);
    		this.item = newItem;
    	}
    	photos = new ArrayList<Photo>();
    	ItemManager.instance().addItemManagerListener(this);
    	
    	this.setLayout(new BorderLayout());

    	/* Preview Panel setup */
    	previewPanel = new PhotoPanel(320,240);
		previewPanel.setDropMode(true);
    	previewPanel.enablePopup();
    	previewPanel.setMinimumSize(new Dimension(600,300));
    	
    	setUp();
    }
    
    public void setUp() 
    {
    	this.removeAll();
    	photos.clear();

    	final JSplitPane parent = (JSplitPane) this.getParent();
    	if (parent != null)
    		parent.setDividerLocation(0.565);

    	multimediaModified = false;
    	preview = null;
    	
    	previewPanel.clearPhotoPanelListeners();
    	previewPanel.addPhotoPanelListener(this);
    	if (item != null) {
    		this.itemClass = item.getItemClass();
    		try {
    			final Photo preview = (Photo)item.getPreview();
    			final List<Photo> photos = item.getPhotos();
    			previewPanel.setContent(null);
    			if (preview != null) {
    				previewPanel.setContent(null);
    				for (final Photo photo : photos) {
    					if (photo.getId().equals(preview.getId())) {
    						this.preview = photo;
    						previewPanel.setContent(photo);
    					}
    				}
    			}
    			this.photos.addAll(photos);
    		} 
    		catch (Exception e) { /* Do nothing */ }
    	}
    	
    	final JPanel flowPanel = new JPanel(new FlowLayout());
    	fieldsPanel = new FieldSelectorPanel(item, linkedItemTable.getRealColumns(item)); // Fields panel
    	flowPanel.add(fieldsPanel);
    	flowPanel.setBackground(Color.WHITE);
    	final JScrollPane scrollFieldsPanel = new JScrollPane(flowPanel);
    	slidingWindow = new MultimediaSelectorPanel(photos, 960, previewPanel); // sliding window of photos
    	slidingWindow.setMinimumSize(new Dimension(Short.MAX_VALUE,95));
        JSPH = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,previewPanel, scrollFieldsPanel);
        JSPV = new JSplitPane(JSplitPane.VERTICAL_SPLIT,JSPH,slidingWindow);
        JSPV.setDividerSize(1);
        JSPV.setEnabled(false);
        JSPH.setDividerSize(5);
        previewPanel.setBackground(Color.WHITE);
        fieldsPanel.setBackground(Color.WHITE);
        slidingWindow.setBackground(Color.WHITE);
        JSPV.setDividerSize(5);
        JSPH.setDividerLocation(600);
        JSPV.setDividerLocation(300);
        JSPV.setResizeWeight(1.0);
    	this.add(JSPV);
    	this.revalidate();
    	this.repaint();

    }
    
    public void setItemDisplayed(final Item item)
    {
    	
    	if(item != null && !(item.equals(this.item))) {
    		fieldsPanel.save(preview, photos, isMultimediaModified());
    		this.item = item;
    		itemClass = item.getItemClass();
    		this.remove(JSPV);
    		setUp(); 
    		fireItemChanged();	
    	}
    }
    
	private boolean photosModified ()
	{
		for (final Photo photo : photos) {
			if (photo.isModified())
				return true;
		}
		return false;
	}

    //manage listeners 
    
    public void addListener(final ItemEditorListener li)
    {
    	listeners.add(li);
    	li.itemChanged(item);
    }
    
    public void removeListener(final ItemEditorListener li)
    {
    	listeners.remove(li);
    }
    
    
    private void fireItemChanged()
	{
		for(final ItemEditorListener li : listeners)
			li.itemChanged(item);
	}

    
    //Iterfaces implemenation methods 
    
    
    
    //Item table listen methods
	public void itemSelected(final UOMItemJTable table,final Item item) {
		setItemDisplayed(item);
	}

	public void searchChanged(final UOMItemJTable table,final  boolean state) { return; }
	public void tableHidden(final UOMItemJTable table) { return; }
	public void tableShown(final UOMItemJTable table) { return; }

	
	//itemManager listen methods
	
	public void databaseClosed() { item = null; previewPanel.setContent(null); setUp(); }
	
	public void databaseOpened() { return; }

	public void elementDeleted(final Element e) {
		if (e.equals(itemClass)) {
			item = null;
			itemClass = null;
			previewPanel.setContent(null);
			setUp();
			return;
		}
		else if (!e.equals(item))
			return;
		final Item firstChoiceItem = linkedItemTable.getItem(0);
		if(firstChoiceItem != null){
			setItemDisplayed(firstChoiceItem);
			return;
		}
		setItemDisplayed(ItemManager.instance().itemAdd(itemClass, false));
	}

	
	
	public void elementModified(final Element e) {
		if (e.equals(item))
			setItemDisplayed((Item) e);
		else if (itemClass != null && e.getName().equals(itemClass.getName()))
		{
			this.itemClass = (ItemClass) e;
			//final Item i = item;
			setUp();
			//setItemDisplayed(null);
			//setItemDisplayed(i);
		}
	}

	
		
	public void itemAdded(final Item i) {
		setItemDisplayed(i);		
	}

	public void itemClassAdded(final ItemClass c) { return; }
	
	public void focusOnItem (final Item i) { 
		setItemDisplayed(i);
	}

	

	//ItemClass listen to methods 
	public void itemClassesSelected(final UOMItemClassJTable table,final Set<ItemClass> itemClasses) {
		
		Item firstChoiceItem = linkedItemTable.getItem(0);
		if(firstChoiceItem != null){
			setItemDisplayed(firstChoiceItem);
			return;
		}
		if(itemClasses.size() > 0){
			final Iterator<ItemClass> itIC = itemClasses.iterator();
			ItemClass newItemClass = null;
			while(itIC.hasNext()){
				ItemClass nextItemClass = itIC.next();
				if(!nextItemClass.getName().contains("ALL CATEGORIES"))
				{
					newItemClass = nextItemClass;
					break;
				}
			}
			if(newItemClass != null) {
				Item newItem = null;
				try {
					final Set<Item> items = ItemManager.instance().getItemsFromItemClass(newItemClass);
					final Iterator<Item> it = items.iterator();
					if(it.hasNext())
						newItem = items.iterator().next();
				}
				catch (final Exception ex) {
					ex.printStackTrace();
				} 
				if(newItem == null) {
					newItem = ItemManager.instance().itemAdd(newItemClass,false);
				}
				setItemDisplayed(newItem);
			}
		}
	}

	public void tableHidden(final UOMItemClassJTable table) { return; }
	public void tableShown(final UOMItemClassJTable table) { return; }
	
	public void photoAdded (final PhotoPanel panel, final Photo photo)
	{
		multimediaModified = true;
		photos.add(photo);
		if (preview == null)
			setPreview(null,photo);
	}
	
	public void photoRemoved (final PhotoPanel panel, final Photo photo)
	{
		if (preview.equals(photo))
			preview = null;
		if (!photos.contains(photo))
			return;
		multimediaModified = true;
		int i = 0;
		for (i = 0; i < photos.size(); i++) {
			if (photos.get(i).equals(photo))
				break;
		}
		photos.remove(photo);
		if (i < photos.size())
			setPreview(null, photos.get(i));
		else if ((i -1) >= 0)
			setPreview(null,photos.get(i - 1));
		else
			setPreview(null, null);
	}
	
	public void setPreview (final PhotoPanel panel, final Photo photo)
	{
		multimediaModified = true;
		preview = photo;
	}
	
	public void newContentDisplayed (final PhotoPanel panel, final Photo photo) {
		if (preview == null)
			setPreview(panel, photo);
	}

	public void saveItemPushed() {
		fieldsPanel.saveFromMenu(preview, photos, isMultimediaModified());
		fireItemChanged();
	}
	
	private boolean isMultimediaModified ()
	{
		try {
			if (item == null)
				return false;
			else if (item.isNew())
				return (multimediaModified && photosModified());
			else
				return (multimediaModified || photosModified());
		}
		catch (final UOMException uome) {
			return false;
		}
	}
}
